package com.bss;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.springframework.transaction.annotation.Transactional;

public class GenericDAO<T> {
	// private final static String UNIT_NAME = "EPORTALDBPU";

	private EntityManager em;

	public EntityManager getEm() {
		return em;
	}

	public void setEm(EntityManager em) {
		this.em = em;
	}

	private Class<T> entityClass;

	public GenericDAO(Class<T> entityClass) {

		this.entityClass = entityClass;
	}

	
	public void save(T entity) {		
		em.persist(entity);		
	}

	public void delete(T entity) {
		T entityToBeRemoved = em.merge(entity);

		em.remove(entityToBeRemoved);
	}

	public T update(T entity) {
		return em.merge(entity);
	}

	public T find(int entityID) {
		return em.find(entityClass, entityID);
	}

	// Using the unchecked because JPA does not have a
	// em.getCriteriaBuilder().createQuery()<T> method
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public List<T> findAll() {

		try {
			return this.em.createQuery("from " + this.entityClass.getName())
					.getResultList();
		} catch (RuntimeException re) {
			throw re;
		}
	}

	// Using the unchecked because JPA does not have a
	// ery.getSingleResult()<T> method
	@SuppressWarnings("unchecked")
	protected T findOneResult(String namedQuery, Map<String, Object> parameters) {
		T result = null;

		Query query = em.createNamedQuery(namedQuery);

		// Method that will populate parameters if they are passed not null and
		// empty
		if (parameters != null && !parameters.isEmpty()) {
			populateQueryParameters(query, parameters);
		}
		result = (T) query.getSingleResult();

		return result;
	}

	@SuppressWarnings("unchecked")
	protected T findResultList(String namedQuery, Map<String, Object> parameters) {
		T result = null;

		Query query = em.createNamedQuery(namedQuery);

		// Method that will populate parameters if they are passed not null and
		// empty
		if (parameters != null && !parameters.isEmpty()) {
			populateQueryParameters(query, parameters);
		}

		result = (T) query.getResultList();

		return result;
	}

	@SuppressWarnings("unchecked")
	protected List<T> findNewResultList(String namedQuery,
			Map<String, Object> parameters) {
		List<T> result = null;

		Query query = em.createNamedQuery(namedQuery);

		// Method that will populate parameters if they are passed not null and
		// empty
		if (parameters != null && !parameters.isEmpty()) {
			populateQueryParameters(query, parameters);
		}

		result = query.getResultList();

		return result;
	}

	private void populateQueryParameters(Query query,
			Map<String, Object> parameters) {

		for (Entry<String, Object> entry : parameters.entrySet()) {
			query.setParameter(entry.getKey(), entry.getValue());
		}
	}
}
